/*
 * Copyright (c) 2012 by Chances.
 * $CVSHeader$
 * $Author$
 * $Date$
 * $Revision$
 */
package chances.wechat.controller;

import java.rmi.RemoteException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import chances.wechat.data.PageBean;
import chances.wechat.entity.QrCodeInfo;
import chances.wechat.entity.StbInfo;
import chances.wechat.entity.WechatStbBind;
import chances.wechat.entity.WechatUser;
import chances.wechat.model.BindEvent;
import chances.wechat.msggw.context.QrBindContext;
import chances.wechat.msggw.context.QrContext;
import chances.wechat.msggw.resp.BindResponse;
import chances.wechat.msggw.resp.QrResponse;
import chances.wechat.repository.QrCodeRepository;
import chances.wechat.repository.UserRepository;
import chances.wechat.resp.ResultResponse;
import chances.wechat.service.BindService;
import chances.wechat.utils.RequestUtils;

/**
 * Class comments.
 * 
 * @author <a href="mailto:libf@chances.com.cn">libf</a>
 */
public abstract class UserAbstractController {
    @Autowired
    protected BindService bindService;

    @Autowired
    protected QrCodeRepository qrCodeRepository;

    @Autowired
    protected UserRepository userRepository;

    @Autowired
    ApplicationContext applicationContext;

    public static final int SUCCESS = 200;
    public static final int VALID_PARAM = 1001;
    public static final int VALID_TOKEN = 1002;

    public static final int DB_ERROR = 9001;
    public static final int SYS_ERROR = 9002;

    private static final String FIX = "|";

    private static final Logger login = LoggerFactory
            .getLogger("userloginLogger");

    private static final Logger unbind = LoggerFactory
            .getLogger("unbindLogger");

    private static final Logger bind = LoggerFactory.getLogger("bindLogger");

    private static Logger error = LoggerFactory.getLogger("errorLogger");

    public void logLogin(String appId, String openId, String scope, String type,
            String target) {
        StringBuffer sb = new StringBuffer();
        sb.append(appId).append(FIX).append(openId).append(FIX).append(scope)
                .append(FIX).append(type).append(FIX).append(target);
        login.info(sb.toString());
    }

    public void logStbUnbind(String openId, String stbNo, String bindId,
            String resultJson) {
        StringBuffer sb = new StringBuffer();
        sb.append(openId).append(FIX).append(stbNo).append(FIX).append(bindId)
                .append(FIX).append(resultJson);
        unbind.info(sb.toString());
    }

    public void logStbBind(String openId, String stbNo, String qrcodeurl,
            String bindId, String bindUrl, String resultJson) {
        StringBuffer sb = new StringBuffer();
        sb.append(openId).append(FIX).append(stbNo).append(FIX)
                .append(qrcodeurl).append(FIX).append(bindId).append(FIX)
                .append(bindUrl).append(FIX).append(resultJson);
        bind.info(sb.toString());
    }

    protected PageBean getPageBean(HttpServletRequest request) {
        int curPage = RequestUtils.getParameter(request, "pageIndex", 1);
        int size = RequestUtils.getParameter(request, "pageSize", 20);
        PageBean pageBean = new PageBean(size);
        pageBean.setCurrentPage(curPage);
        return pageBean;
    }

    protected StbInfo createStbEntity(QrCodeInfo qrInfo) {
        StbInfo aStbInfo = new StbInfo();
        aStbInfo.setCreateTime(new Date());
        aStbInfo.setLastLoginTime(new Date());
        aStbInfo.setStbNo(qrInfo.getStbNo());
        aStbInfo.setStbType(qrInfo.getScene());
        aStbInfo.setEpgGroup(qrInfo.getLocation());
        return aStbInfo;
    }
    /**
     * 更新用户
     * 
     * @param bind
     */
    protected void updateBindStatus(WechatStbBind bind) {
        try {
            this.bindService.updateBindStatus(bind);
        } catch (Throwable ex) {

        }

    }
    public ResultResponse<String> deviceBind(WechatUser user, String code) {
        String userId = user.getOpenId();
        ResultResponse<String> result = new ResultResponse<String>();
        QrCodeInfo qrCodeInfo = qrCodeRepository.getQrCodeByQrInfo(code);
        StbInfo stbInfo = this.userRepository
                .findStbInfo(qrCodeInfo.getStbNo());
        if (stbInfo == null) {
            stbInfo = this.createStbEntity(qrCodeInfo);
            this.userRepository.insertStbInfo(stbInfo);
        }

        WechatStbBind userBind = this.bindService.query(userId,
                qrCodeInfo.getStbNo());

        result.setStatus(SUCCESS);
        if (userBind == null) {
            try {
                user.setCurrentStbNo(qrCodeInfo.getStbNo());
                String qrcodeurl = this.getBindUrl(qrCodeInfo);
                BindResponse bindResponse = this.bindQr(user, qrcodeurl);
                logStbBind(user.getOpenId(), qrCodeInfo.getStbNo(),
                        qrCodeInfo.getQrInfo(), bindResponse.getBindid(),
                        qrcodeurl, bindResponse.getContent());
                userBind = this.userRepository.bind(user, stbInfo,
                        bindResponse.getBindid());
                this.userRepository.updateUserMasterStbNo(
                        user.getCurrentStbNo(), user.getOpenId());
                result.setMessage(bindResponse.getContent());
            } catch (Throwable ex) {
                error.error("find fail, userId:{}", userId);
                error.error(ex.toString(), ex);
                ex.printStackTrace();
                result.setStatus(DB_ERROR);
            }
        } else {
            this.updateBindStatus(userBind);
        }

        BindEvent bindEvent = new BindEvent(userId, code, stbInfo,
                BindEvent.TYPE_BIND);
        try {
            this.applicationContext.publishEvent(bindEvent);
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return result;
    }

    protected String getBindUrl(QrCodeInfo qrCodeInfo) {
        String qrcodeurl = null;
        QrContext qrContext = new QrContext("getqrcode");
        qrContext.setIptvacct(qrCodeInfo.getStbNo());
        qrContext.setStbtype(qrCodeInfo.getScene());
        qrContext.setEpgversion(qrCodeInfo.getLocation());

        QrResponse qrResponse;
        try {
            qrResponse = bindService.getQrCode(qrContext);
            qrcodeurl = qrResponse.getQrcodeurl();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return qrcodeurl;
    }

    protected BindResponse bindQr(WechatUser aUser, String url) {
        QrBindContext qrBindContext = new QrBindContext();
        qrBindContext.setAppacct(aUser.getId() + "");
        qrBindContext.setUsername(aUser.getNickname());
        qrBindContext.setBindUrl(url);
        BindResponse bindResponse = new BindResponse();
        try {
            bindResponse = bindService.bind(qrBindContext);
        } catch (RemoteException e) {
        }
        return bindResponse;
    }
}
